<?php
/**
 * CDbConfig class file.
 * 获取或设置数据库配置数据.
 * @author Huan Song <iphper@yeah.net>
 * @version $Id: CDbConfig.php 1 2011-01-12 20:36:16Z huan.song $
 * @package system.db
 * @since 2.0
 */
class CDbConfig extends CConfig
{
	/**
	 * @var string Data Source Name.
	 */
    protected static $_dsn;
    
    /**
	 * @var string 数据库用户名.
	 */
    protected static $_username;
    
    /**
	 * @var string 数据库密码.
	 */
    protected static $_password;
    
    /**
	 * @var string 数据库字符编码.
	 */
    protected static $_charset;
    
    /**
	 * @var string 数据库前缀.
	 */
    protected static $_prefix;
    
    /**
     * 通过列名获取数据时, 列名大小写规则.
     * Options
     * PDO::CASE_NATURAL (default) 默认方式.
     * PDO::CASE_LOWER 列名小写.
     * PDO::CASE_UPPER 列名大写.
     * @var integer.
     */
    protected static $_caseFolding;
    
	/**
	 * 获取Data Source Name.
	 * <pre>
	 * $dsn = CDbConfig::getDsn();
	 * </pre>
	 * @return string Data Source Name.
	 * @see setDsn
	 */
	public static function getDsn()
	{
		if (null === self::$_dsn)
			self::setDsn();
		
		return self::$_dsn;
	}
	
	/**
	 * 设置Data Source Name.
	 * <pre>
	 * $dsn = null;
	 * CDbConfig::setDsn($dsn);
	 * 如果$dsn === null, 取配置中
	 * 'db' => array(
	 * 		'dsn' => 'mysql:host=localhost;dbname=vivo',
	 * 	),
	 * 结果: self::$_dsn = 'mysql:host=localhost;dbname=vivo'.
	 * </pre>
	 * @param string|null $dsn. 如果为null, 取用户自定义的dsn.
	 * @throws CDbException. 如果没有设置配置dsn, 抛出异常.
	 * @see getDsn
	 */
	public static function setDsn($dsn = null)
	{
		if (null === $dsn)
		{
			$dsn = self::get('db', 'dsn');
			if (null === $dsn)
				throw new CDbException('CDbConfig:setDsn dsn not set');
		}
		
		self::$_dsn = $dsn;
	}
	
	/**
	 * 获取数据库类型, 从$_dsn中取.
	 * <pre>
	 * $dbType = CDbConfig::getDbType();
	 * </pre>
	 * @return string 数据库类型.
	 */
	public static function getDbType()
	{
		return strtolower(substr(self::getDsn(), 0, strpos(self::getDsn(), ':')));
	}
	
	/**
	 * 获取数据库用户名.
	 * <pre>
	 * $username = CDbConfig::getUsername();
	 * </pre>
	 * @return string 数据库用户名.
	 * @see setUsername
	 */
	public static function getUsername()
	{
		if (null === self::$_username)
			self::setUsername();
		
		return self::$_username;
	}
	
	/**
	 * 设置数据库用户名.
	 * <pre>
	 * $username = null;
	 * CDbConfig::setUsername($username);
	 * 如果$username === null, 取配置中
	 * 'db' => array(
	 * 		'username' => 'root',
	 * 	),
	 * 结果: self::$_username = 'root'.
	 * </pre>
	 * @param string|null $username. 如果为null, 取用户自定义的数据库用户名.
	 * @throws CDbException. 如果没有设置数据库用户名, 抛出异常.
	 * @see getUsername
	 */
	public static function setUsername($username = null)
	{
		if (null === $username)
		{
			$username = self::get('db', 'username');
			if (null === $username)
				throw new CDbException('CDbConfig:setUsername username not set');
		}
		
		self::$_username = $username;
	}
	
	/**
	 * 获取数据库密码.
	 * <pre>
	 * $password = CDbConfig::getPassword();
	 * </pre>
	 * @return string 数据库密码.
	 * @see setPassword
	 */
	public static function getPassword()
	{
		if (null === self::$_password)
			self::setPassword();
		
		return self::$_password;
	}
	
	/**
	 * 设置数据库密码.
	 * <pre>
	 * $password = null;
	 * CDbConfig::setPassword($password);
	 * 如果$password === null, 取配置中
	 * 'db' => array(
	 * 		'password' => '',
	 * 	),
	 * 结果: self::$_password = ''.
	 * </pre>
	 * @param string|null $password. 如果为null, 取用户自定义的数据库密码.
	 * @throws CDbException. 如果没有设置数据库密码, 抛出异常.
	 * @see getPassword
	 */
	public static function setPassword($password = null)
	{
		if (null === $password)
		{
			$password = self::get('db', 'password');
			if (null === $password)
				throw new CDbException('CDbConfig:setPassword password not set');
		}
		
		self::$_password = $password;
	}
	
	/**
	 * 获取数据库字符编码.
	 * <pre>
	 * $charset = CDbConfig::getCharset();
	 * </pre>
	 * @return string 数据库字符编码.
	 * @see setCharset
	 */
	public static function getCharset()
	{
		if (null === self::$_charset)
			self::setCharset();
		
		return self::$_charset;
	}
	
	/**
	 * 设置数据库字符编码.
	 * <pre>
	 * $charset = null;
	 * CDbConfig::setCharset($charset);
	 * 如果$charset === null, 取配置中
	 * 'db' => array(
	 * 		'charset' => 'UTF8',
	 * 	),
	 * 结果: self::$_charset = 'UTF8'.
	 * </pre>
	 * @param string|null $charset. 如果为null, 取用户自定义的数据库字符编码; 如果没有设置配置$charset, 默认为'UTF8'.
	 * @see getCharset
	 */
	public static function setCharset($charset = null)
	{
		if (null === $charset)
			$charset = self::get('db', 'charset');
		
		self::$_charset = $charset;
	}
	
	/**
	 * 获取表前缀.
	 * <pre>
	 * $prefix = CDbConfig::getPrefix();
	 * </pre>
	 * @return string 表前缀.
	 * @see setPrefix
	 */
	public static function getPrefix()
	{
		if (null === self::$_prefix)
			self::setPrefix();
		
		return self::$_prefix;
	}
	
	/**
	 * 设置数据库前缀.
	 * <pre>
	 * $prefix = null;
	 * CDbConfig::setPrefix($prefix);
	 * 如果$prefix === null, 取配置中
	 * 'db' => array(
	 * 		'prefix' => '',
	 * 	),
	 * 结果: self::$_prefix = ''.
	 * </pre>
	 * @param string|null $prefix. 如果为null, 取用户自定义的数据库前缀; 如果没有设置配置$prefix, 默认为''.
	 * @see getPrefix
	 */
	public static function setPrefix($prefix = null)
	{
		if (null === $prefix)
		{
			$prefix = self::get('db', 'prefix');
			if (null === $prefix)
				$prefix = '';
		}
		
		self::$_prefix = $prefix;
	}
	
	/**
	 * PDO通过列名获取数据时, 列名大小写规则.
	 * <pre>
	 * $caseFolding = CDbConfig::getCaseFolding();
	 * </pre>
	 * @return string 通过列名获取数据时, 列名大小写规则.
	 * @see setCaseFolding
	 */
	public static function getCaseFolding()
	{
		if (null === self::$_caseFolding)
			self::setCaseFolding();
		
		return self::$_caseFolding;
	}
	
	/**
	 * 设置通过列名获取数据时, 列名大小写规则.
	 * <pre>
	 * $caseFolding = null;
	 * CDbConfig::setCaseFolding($caseFolding);
	 * 如果$caseFolding === null, 取配置中
	 * 'db' => array(
	 * 		'caseFolding' => PDO::CASE_NATURAL,
	 * 	),
	 * 结果: self::$_caseFolding = PDO::CASE_NATURAL.
	 * </pre>
	 * @param string|null $caseFolding. 如果为null, 取用户自定义的; 如果没有设置配置$caseFolding, 默认为PDO::CASE_NATURAL.
	 * @throws CDbException. 如果$caseFolding不是PDO::CASE_NATURAL|PDO::CASE_LOWER|PDO::CASE_UPPER, 抛出异常.
	 * @see getCaseFolding
	 */
	public static function setCaseFolding($caseFolding = null)
	{
		if (null === $caseFolding)
		{
			$caseFolding = self::get('db', 'caseFolding');
			if (null === $caseFolding)
				$caseFolding = PDO::CASE_NATURAL;
		}
		
		self::$_caseFolding = (int) $caseFolding;
		
		if (!in_array(self::$_caseFolding, array(PDO::CASE_NATURAL, PDO::CASE_LOWER, PDO::CASE_UPPER)))
			throw new CDbException('CDbConfig:setCaseFolding invalid caseFolding', array('{caseFolding}' => self::$_caseFolding));
	}
}
